package com.jule.teenpatti.game.network.protocol.reqs;

import JoloProtobuf.GameSvr.JoloGame;
import com.jule.core.common.log.LoggerUtils;
import com.jule.teenpatti.base.enums.ErrorCodeEnum;
import com.jule.teenpatti.base.enums.GameConst;
import com.jule.teenpatti.game.dao.bean.CommonConfigModel;
import com.jule.teenpatti.game.gameUtil.GameLogic;
import com.jule.teenpatti.game.model.PlayerInfo;
import com.jule.teenpatti.game.model.eenum.PlayTypeEnum;
import com.jule.teenpatti.game.model.eenum.PlayerStateEnum;
import com.jule.teenpatti.game.network.protocol.ClientReq;
import com.jule.teenpatti.game.network.protocol.acks.JoloGame_ApplyChooseUserAck_50011;
import com.jule.teenpatti.game.play.AbstractTable;
import com.jule.teenpatti.game.service.TableService;
import com.jule.teenpatti.game.utils.log.TableLogUtil;
import com.jule.teenpatti.game.vavle.notice.NoticeBroadcastMessages;
import io.netty.buffer.ByteBuf;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

public class JoloGame_ApplyChooseUserReq_50011 extends ClientReq {
    private long time;
    private final static Logger logger = LoggerFactory.getLogger(JoloGame_ApplyChooseUserReq_50011.class);

    public JoloGame_ApplyChooseUserReq_50011(int functionId) {
        super(functionId);
    }

    private JoloGame.JoloGame_ApplyChooseUserReq req;


    @Override
    public void readPayLoadImpl(ByteBuf buf) throws Exception {
        time = System.currentTimeMillis();
        byte[] blob = new byte[buf.readableBytes()];
        buf.readBytes(blob);
        req = JoloGame.JoloGame_ApplyChooseUserReq.parseFrom(blob);
        AbstractTable table = TableService.getInstance().getTable(header.gameId + "", req.getRoomId(), req.getTableId());
        if (null != table) {
            this.setTable(table);
        } else {
            logger.error("桌子不存在,roomId->" + req.getRoomId() + ", tableId->" + req.getTableId());
        }
    }

    @Override
    public void processImpl() throws Exception {
        logger.debug("收到消息-> " + functionId + " reqNum-> " + header.reqNum + "msg ->" + req.toString());
        JoloGame.JoloGame_ApplyChooseUserReq.Builder builder = JoloGame.JoloGame_ApplyChooseUserReq.newBuilder();
        String userId = req.getUserId();
        String roomId = req.getRoomId();
        String tableId = req.getTableId();
        String gameOrderId = req.getGameOrderId();
        String targetUserId = req.getTargetUserId();

        AbstractTable table = getTable();

        JoloGame.JoloGame_ApplyChooseUserAck.Builder ack = JoloGame.JoloGame_ApplyChooseUserAck.newBuilder();
        ack.setUserId(userId);
        ack.setRoomId(roomId);
        ack.setTableId(tableId);
        ack.setGameOrderId(gameOrderId);
        ack.setTargetUserId(targetUserId);
        try {
            //判断GameOrderId是否一致
            if (!gameOrderId.equals(table.getCurrGameOrderId())) {
                ack.setResult(-1);
                logger.error("GameOrderId不匹配, currGameOrderId->" + table.getCurrGameOrderId() + ", gameOrderId->" + gameOrderId);
                ack.setResultMsg(ErrorCodeEnum.GAME_50013_2.getCode());
                ctx.writeAndFlush(new JoloGame_ApplyChooseUserAck_50011(ack.build(), header));
                return;
            }

            PlayerInfo player = table.getPlayer(userId);
            PlayerInfo targetPlayer = table.getPlayer(targetUserId);
            if (null == player || null == targetPlayer) {
                ack.setResult(-1); //玩家信息不存在
                logger.info("找不到玩家信息。playerIsNull->" + (null == player) + ", targetPlayerIsNull->" + (null == targetPlayer));
                ack.setResultMsg(ErrorCodeEnum.GAME_50050_2.getCode());
                ctx.writeAndFlush(new JoloGame_ApplyChooseUserAck_50011(ack.build(), header));
                return;
            }

            //根据玩法配置信息，判断是否允许“选择指定用户”进行比牌
            CommonConfigModel commonConfig = table.getCommonConfig();
//            if (null == commonConfig) {
//                throw new Exception("can't found CommonConfig, playType->" + PlayTypeEnum.classic);
//            }
            if (!commonConfig.isChooseSideShowUser()) {
                //如果“不允许指定”被比牌玩家，那么返回错误信息
                ack.setResult(-2);
                logger.error("牌桌禁止使用选择比牌用户的功能");
                ack.setResultMsg(ErrorCodeEnum.GAME_50011_1.getCode());
                ctx.writeAndFlush(new JoloGame_ApplyChooseUserAck_50011(ack.build(), header));
                return;
            }

            //判断player的状态是否合法
            if (player.getState() == PlayerStateEnum.fold || player.getState() == PlayerStateEnum.showfail) {
                ack.setResult(-3);
                logger.error("玩家已弃牌，不能进行比牌");
                ack.setResultMsg(ErrorCodeEnum.GAME_50011_2.getCode());
                ctx.writeAndFlush(new JoloGame_ApplyChooseUserAck_50011(ack.build(), header));
                return;
            }

            //判断targetUser的状态是否合法
            if (targetPlayer.getState() == PlayerStateEnum.fold || player.getState() == PlayerStateEnum.showfail) {
                ack.setResult(-3);
                logger.error("目标玩家已弃牌，不能跟已弃牌玩家比牌");
                ack.setResultMsg(ErrorCodeEnum.GAME_50011_3.getCode());
                ctx.writeAndFlush(new JoloGame_ApplyChooseUserAck_50011(ack.build(), header));
                return;
            }

            //返回服务器接收信息正确的回复
            ctx.writeAndFlush(new JoloGame_ApplyChooseUserAck_50011(ack
                    .setResult(1)
                    .build(), header));

            table.setLastActionTime(System.currentTimeMillis());

            TableLogUtil.chooseUser(functionId, "chooseUser", userId, player.getNickName(), table.getPlayType() + "",
                    table.getRoomId(), table.getTableId(), table.getCurrGameOrderId(), targetUserId);
            //记录当前发起比牌者的id
            table.setCurrDoSideShowPlayerId(userId);
            table.setCurrTargetSideShowPlayerId(targetUserId);

//            if (commonConfig.isChooseSideShowUser()) {
//                //广播事件：通知所有牌桌内玩家，需要等待指定玩家是否同意比牌的倒计时
//                NoticeBroadcastMessages.sideShowWaitTargetUserAllow(table, targetPlayer.getPlayerId());
//                GameLogic.waitUserAllowSideShowCD(table, player, targetPlayer);
//            } else {
                //启动比牌倒计时
                List<String> list = new ArrayList<>();
                list.add(player.getPlayerId());
                list.add(targetPlayer.getPlayerId());
                //通知所有人有人sideshow
                NoticeBroadcastMessages.bothSideshows(table, list);
//            }
            long timeMillis = System.currentTimeMillis() - time;
            if (timeMillis > GameConst.COST_TIME) {
                LoggerUtils.performance.info("ApplyChooseUserReq_50011,cost time:{},req:{}", timeMillis, req.toString());
            }
        } catch (Exception ex) {
//            logger.error("系统异常：userId->"+userId+", gameOrderId->"+gameOrderId+", message->"+ex.getMessage());
//            ack.setResult(-1);
//            ack.setResultMsg(ex.getMessage());
//            ctx.writeAndFlush(new JoloGame_ApplyChooseUserAck_50011(ack.build(), header));
        } finally {
//            logger.debug("ChooseUser ACK info: "+ack.toString());
//            logger.debug("ChooseUser ACK bytes length: "+ack.build().toByteArray().length);
//            if(null != table){
//                logger.debug("All Player info: "+System.getProperty("line.separator") + table.toStringAllPlayers());
//
//                logger.debug("InGame Player info: "+System.getProperty("line.separator") + table.toStringInGamePlayers());
//            }
//            logger.debug("ChooseUser over. Table state: "+table.getTableStateEnum());

            long useTimes = System.currentTimeMillis() - time;
            if(useTimes > 10) {
                logger.error("ApplyChooseUser。 耗时->{} 毫秒, reqNum->{}", useTimes, header.reqNum); //TODO:临时增加
            }
        }
    }
}
